// Copyright (c) 2009, Michael Patraw
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * The name of Michael Patraw may not be used to endorse or promote 
//       products derived from this software without specific prior written
//       permission.
//
// THIS SOFTWARE IS PROVIDED BY Michael Patraw ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Michael Patraw BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>

#include "time.h"

const unsigned int NUM_SEASONS = 4;
const unsigned int NUM_HOURS = 24;

const unsigned int NIGHT1 = 48; // 0000-0559
const unsigned int DAWN = 108; // 0600-859
const unsigned int DAY = 192;  // 0900-1559
const unsigned int DUSK = 240; // 1600-1959
const unsigned int NIGHT2 = 288; // 2000-2359

const unsigned int Time::MINUTES_IN_TURN = 5;
const unsigned int Time::TURNS_IN_HOUR = 12;
const unsigned int Time::TURNS_IN_DAY = TURNS_IN_HOUR * NUM_HOURS;
const unsigned int Time::TURNS_IN_SEASON = TURNS_IN_DAY * 91;
const unsigned int Time::TURNS_IN_YEAR = TURNS_IN_SEASON * NUM_SEASONS;

Time::Time() :
turns_(0)
{

}

void Time::update()
{
    ++turns_;
}

void Time::reset()
{
    turns_ = 0;
}

const char * Time::getTime() const
{
    std::stringstream ss;
    unsigned int h, m;
    std::string ampm = "AM";
    // Get time of day.
    h = getHour();
    m = getMinute();
    
    if (h > 12) {
        h -= 12;
        ampm = "PM";
    }
    else if (h == 0) {
        h = 12;
    }
    
    ss << h << ":";
    
    if (m < 10)
        ss << "0";
    
    ss << m << ampm << ", Day: " << getDay() << ", Year: " << getYear(); 
    
    return ss.rdbuf()->str().c_str();
}

bool Time::isDay() const
{
    if (turns_ % TURNS_IN_DAY < DAY && turns_ % TURNS_IN_DAY >= DAWN)
        return true;
    return false;
}

bool Time::isNight() const
{
    if (turns_ % TURNS_IN_DAY < NIGHT1 || turns_ % TURNS_IN_DAY >= DUSK)
        return true;
    return false;
}

bool Time::isDusk() const
{
    if (turns_ % TURNS_IN_DAY < DUSK && turns_ % TURNS_IN_DAY >= DAY)
        return true;
    return false;
}

bool Time::isDawn() const
{
    if (turns_ % TURNS_IN_DAY < DAWN && turns_ % TURNS_IN_DAY >= NIGHT1)
        return true;
    return false;
}

int Time::isAm() const
{
    return getHour() < 12;
}

int Time::isPm() const
{
    return getHour() >= 12;
}

int Time::getMinute() const
{
    return (turns_ % TURNS_IN_HOUR) * MINUTES_IN_TURN;
}

int Time::getHour() const
{
    return (turns_ % TURNS_IN_DAY) / TURNS_IN_HOUR;
}

int Time::getDay() const
{
    return (turns_ % TURNS_IN_YEAR) / TURNS_IN_DAY;
}

int Time::getSeason() const
{
    return (turns_ % TURNS_IN_YEAR) / TURNS_IN_SEASON;
}

int Time::getYear() const
{
    return turns_ / TURNS_IN_YEAR; 
}
